#pragma once
#include <HscAPI.h>
#include <list>
#include <string>
#include <functional>
#include <HscViewBase.h>

struct DeviceInfo
{
	int id;
	std::string serialNum;
	std::string ipAddress;
};

class CameraDriver;

enum class CameraStatus
{
	Stop,
	Preview,
	College,
	Record,
	Output
};

enum class CameraMessageType
{
	CollageFinish,
	ExtTrigger,
	FrameRateChange
};

struct CameraImageData
{
	char* imageData;
	int imageHeight;
	int imageWidth;
};

struct CameraRecord
{
	int id;
	HscVideoClipInfo videoClip;
};

enum class CameraTriggerMode {Before,After};
enum class CameraCollegeParaType{Frame,Time};

class CameraMsgHandle : public CHscViewBase
{
public:
	CameraMsgHandle(std::function<void(CameraMessageType,int)> msgHandler) : _msgHandler(msgHandler) {}
	void Update(HscEvent* msg, void* parameters);
private:
	std::function<void(CameraMessageType,int)> _msgHandler;
};

typedef HscVideoClipInfo VideoClipInfo;

struct CameraWindowsSizeAndPos
{
	long width;
	long height;
	long offsetX;
	long offsetY;
};

class CameraDevice
{
private:
	struct CameraCollegePara
	{
		RecordMode mode;
		RecordType type;
		DWORD recordValue;
		DWORD totalValue;
	} collegePara;

public:
	CameraDevice(DeviceHandle _cameraHandle, HscDeviceInfo _deviceInfo,std::function<void(CameraMessageType,int)> msgHandler);
	CameraImageData GetNewPreviewImage();
	CameraImageData GetFirstFrame();
	CameraImageData GetCurrentOutputImage(int recordID, int frameID);
	HscDeviceParam GetDeviceInfo();
	bool isGetNewPreviewImage();

	//Mode
	void PreviewMode();
	void HighSpeedCollegeMode();
	void StopMode();
	void ExportMode(int id);
	void ReturnExportMode();
	void RestartExportMode(int id);

	void StartShot();
	std::list<CameraRecord> GetRecordList();
	int loadFrameToMemory(VideoClipInfo& videoID, long startFrame, long endFrame,int interval);
	void loadFrameToMemory(VideoClipInfo& videoID, long startFrame, long endFrame);
	//Shot Setting
	void SetExpourseTime(long nsTime);
	long GetExpourseTime();
	void SetCollegePeriod(long nsTime);
	long GetCollegePeriod();
	void SetTriggerMode(CameraTriggerMode mode);
	CameraTriggerMode GetTriggerMode();
	void SetTriggerParaType(CameraCollegeParaType type);
	CameraCollegeParaType GetTriggerParaType();
	void SetTriggerValue(long value);
	long GetTriggerValue();
	void SetTriggerTotalValue(long value);
	long GetTriggerTotalValue();
	void SetExpourseDelay(long value);
	long GetExpourseDelay();
	void SetCollegeWindow(CameraWindowsSizeAndPos& cameraWindow);
	CameraWindowsSizeAndPos GetCollegeWindow();

	//Camera Setting
	bool GetCameraOpenStatus();
	void OpenCamera();
	void CloseCamera();
	void DeleteAllVideo();
	int GetTotalMemorySize();
	int GetUsedMemorySize();
	std::string GetCameraSerialNum();
	ExternalTriggerMode GetExternalTriggerMode();
	void SetExternalTriggerMode(const ExternalTriggerMode& setMode);
	bool GetExternalTrigger();
	void SetExternalTrigger(bool triggerMode);
	void SetExtSyncSource(bool extSync);
	bool GetExtSyncSource();
	void SetPulseWidth(long value);
	long GetPulseWidth();

private:
	DeviceHandle Handle;
	HscDeviceInfo deviceInfo;
	friend class CameraDriver;
	CameraStatus cameraStatus = CameraStatus::Stop;
	CameraMsgHandle cameraMsgHandle;
	bool CameraOpenStatus = false;
};

class CameraDriver
{
public:
	CameraDriver();
	virtual ~CameraDriver();
	std::list<DeviceInfo> SearchDevice(const std::string& IPAddress);
	std::list<CameraDevice>::iterator OpenCamera(int id, std::function<void(CameraMessageType, int)> msgHandler);
	void CloseCamera(std::list<CameraDevice>::iterator itr);
};